<?php
/**
 * Description:
 * Author: hezhizheng
 * Date: 2018/6/11
 * Time: 11:15
 * Created by Created by Panxsoft.
 */

namespace App\Http\Controllers\Wechat\V2_3;

use App\Exceptions\ApiErrCode;
use App\Http\Controllers\ApiController;
use App\Http\Controllers\App\WechatUserFavorsController;
use App\Http\Requests\Wechat\FavorBatchDeleteRequest;
use App\Http\Requests\Wechat\FavorUpdateRequest;
use App\Http\Requests\Wechat\FavorIndexRequest;
use App\Http\Requests\Wechat\StoreListRequest;
use App\Models\Customer\Customer;
use App\Models\OpenWechat\ScanEvent;
use App\Models\OpenWechat\WechatUser;
use App\Models\OpenWechat\WechatUserFavor;
use App\Models\Panx\Product;
use App\Models\Store\Store;
use App\Models\Store\StorePivotWechatUser;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;

class FavorController extends ApiController
{
    const ROUTES = [
        'index'   => 'wechat.favor.index',
        'store'   => 'wechat.favor.store',
        'show'    => 'wechat.favor.show',
        'update'  => 'wechat.favor.update',
        'destroy' => 'wechat.favor.destroy',
    ];

    /**
     * @param FavorIndexRequest $request
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function index(FavorIndexRequest $request)
    {
        $wechat_user = WechatUser::findByOpenId($request->openid);
            $this->checkItemExist($wechat_user);

        /** @var LengthAwarePaginator $favors */
        $favors = (new WechatUserFavor)
            ->where('wechat_user_id', $wechat_user->id)
//            ->whereIn('store_id',$store_ids)
            ->when($request->store_id, $this->filterByStoreId())
            ->with(['pack', 'asset', 'store'])
            ->latest('created_at')
            ->paginate($request->per_page ?: 15);

        $favors->each(function (WechatUserFavor $favor) {
            $favor->products = $this->getFavorProducts($favor);
        });

        return $this->response(compact('favors'));
    }

    /**
     * @param WechatUserFavor $favor
     *
     * @return Product[]|\Illuminate\Database\Eloquent\Collection
     */
    private function getFavorProducts(WechatUserFavor $favor)
    {
        // 指定客户（新鸿基）下的商品隐藏, 店铺可能被删除
        $customer_id = $favor->store->customer_id;

        if (Customer::isIdShowFavorProducts($customer_id)) {
            $fav_prods = $favor->getProductsForProductIds();
            $fav_prods->each(function (Product $prod) {
                $prod->append(['link_product']);
            });
        } else {
            $fav_prods = [];
        }

        return $fav_prods;
    }

    /**
     * @test
     * 绑定用户与收藏的关系
     *
     * @uses WechatUserFavorsController::store() - app生成收藏二维码
     *
     * @param FavorUpdateRequest $request
     * @param $favor_id
     *
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function update(FavorUpdateRequest $request, $favor_id)
    {
        // 此个接口应该只做绑定功能。
        // 用户扫 app 生成的收藏二维码，
        // 如果需要记录微信授权登录的用户与店铺的关系，
        // 请求参数需要带上对应的 scan_event_id
        $wechat_user = WechatUser::findByOpenId($request->openid);
            $this->checkItemExist($wechat_user);

        $favor = (new WechatUserFavor)->find($favor_id);
            $this->checkItemExist($favor);

        // 同一个用户申请绑定（H5页面登录情况），直接返回已完成绑定
        if ($wechat_user->id === $favor->wechat_user_id) {
            return $this->response('already bound to you');
        }

        $this->checkUnless(
            $favor->isWechatUserBound(),
            trans('wechat.favor_already_bound'),
            ApiErrCode::WX_USER_IS_BOUND_ERROR
        );

        $binding = $favor->update([
            'wechat_user_id' => $wechat_user->id,
        ]);

        $scan_event_id = $request->scan_event_id;

        /** @var ScanEvent $scan_event */
        $scan_event = (new ScanEvent)->find($scan_event_id);
        $store_id = $scan_event->data['store_id'] ?? null;

        $scan_event->appLogin($wechat_user->id);
        $scan_event->incrementWechatUserVisitStore();
        $this->saveStorePivotWechatUser($wechat_user->id, $store_id);

        return $this->response(compact('binding'));
    }

    /**
     * @test
     *
     * @param $id
     * @return array|\Illuminate\Http\Response
     * @throws \Exception
     */
    public function show($id)
    {
        $favor = (new WechatUserFavor)
            ->with(['store'])
            ->find($id);
            $this->checkItemExist($favor);

        $favor->products = $this->getFavorProducts($favor);

        return $this->response(compact('favor'));
    }

    /**
     * @param FavorBatchDeleteRequest $request
     *
     * @return array|\Illuminate\Http\Response
     * @throws \App\Exceptions\ApiException
     * @throws \Exception
     */
    public function batchDelete(FavorBatchDeleteRequest $request)
    {
        $wechat_user = WechatUser::findByOpenId($request->openid);
            $this->checkItemExist($wechat_user);

        $delete = (new WechatUserFavor)
            ->where('wechat_user_id', $wechat_user->id)
            ->whereIn('id', $request->favor_ids)
            ->delete();

        return $this->response(compact('delete'));
    }

    /**
     * 没有收藏向用户推荐的店铺 （目前没有店铺位置信息，返回所有店铺）
     *
     * @param StoreListRequest $request
     *
     * @return array|\Illuminate\Http\Response
     * @throws \App\Exceptions\ApiException
     * @throws \Exception
     */
    public function storeList(StoreListRequest $request)
    {
        $wechat_user = WechatUser::findByOpenId($request->openid);
            $this->checkItemExist($wechat_user, trans('wechat.wechat_user'));

        $customer_ids = $this->getWechatUserCustomerIds($wechat_user);

        $stores = (new Store)->whereIn('customer_id', $customer_ids)->get();

        return $this->response(compact('stores'));
    }

    /**
     * @param WechatUser $wechat_user
     * @return array
     */
    private function getWechatUserCustomerIds(WechatUser $wechat_user): array
    {
        if ($wechat_user->authorizer) {
            $customer_ids = $wechat_user->authorizer->customers->pluck('id')->all();
        } else {
            $customer_ids = [$wechat_user->customer->id];
        }

        return $customer_ids;
    }

    /**
     * @return \Closure
     */
    private function filterByStoreId(): \Closure
    {
        return function (Builder $builder, int $store_id): void {
            $builder->where(compact('store_id'));
        };
    }

    /**
     * @param $wechat_user_id
     * @param $store_id
     * @return bool
     */
    private function saveStorePivotWechatUser(int $wechat_user_id, int $store_id): bool
    {
        $store_pivot_wechat_user = (new StorePivotWechatUser)
            ->where(compact('wechat_user_id', 'store_id'))
            ->first();

        $store = (new Store)->find($store_id);
        if (! $store_pivot_wechat_user && $store) {
            $store->wechatUsers()->attach($wechat_user_id);
        }

        return true;
    }
}